/**
 * 流量限制器
 * 控制上传/下载速度，防止带宽占满
 */
const logger = require('./logger');

class RateLimiter {
  constructor(maxBytesPerSecond = 170 * 1024 * 1024) { // 默认 170MB/s
    this.maxBytesPerSecond = maxBytesPerSecond;
    this.currentBytes = 0;
    this.lastResetTime = Date.now();
    this.tokens = maxBytesPerSecond; // 令牌桶
    this.waiting = []; // 等待队列
    
    // 每秒重置一次
    this.resetInterval = setInterval(() => {
      this.reset();
    }, 1000);
    
    logger.info(`流量限制器已启动: ${(maxBytesPerSecond / 1024 / 1024).toFixed(2)} MB/s`);
  }

  /**
   * 重置计数器（每秒执行）
   */
  reset() {
    const now = Date.now();
    const elapsed = (now - this.lastResetTime) / 1000;
    
    // 重新填充令牌桶
    this.tokens = Math.min(
      this.maxBytesPerSecond,
      this.tokens + (this.maxBytesPerSecond * elapsed)
    );
    
    this.currentBytes = 0;
    this.lastResetTime = now;
    
    // 处理等待队列
    this.processWaitingQueue();
  }

  /**
   * 处理等待队列
   */
  processWaitingQueue() {
    while (this.waiting.length > 0 && this.tokens > 0) {
      const { bytes, resolve } = this.waiting[0]; // 🔥 先查看不移除
      
      if (bytes <= this.tokens) {
        this.waiting.shift(); // 🔥 确认可以处理后才移除
        this.tokens -= bytes;
        this.currentBytes += bytes;
        resolve();
      } else {
        // 🔥 如果请求太大，检查是否超过单次限制
        if (bytes > this.maxBytesPerSecond) {
          // 请求超过单次限制，部分满足
          this.waiting.shift();
          this.tokens = 0;
          this.currentBytes += this.tokens;
          logger.warn(`流量限制器：请求 ${(bytes / 1024 / 1024).toFixed(2)}MB 超过单次限制 ${(this.maxBytesPerSecond / 1024 / 1024).toFixed(2)}MB/s，部分满足`);
          resolve(); // 🔥 继续执行，避免永久等待
        } else {
          // 等待下一次重置
          break;
        }
      }
    }
  }

  /**
   * 请求发送数据（令牌桶算法）
   * @param {number} bytes - 要发送的字节数
   * @returns {Promise<void>}
   */
  async acquire(bytes) {
    // 如果字节数超过限制，分批处理
    if (bytes > this.maxBytesPerSecond) {
      const chunks = Math.ceil(bytes / this.maxBytesPerSecond);
      const chunkSize = Math.floor(bytes / chunks);
      
      for (let i = 0; i < chunks; i++) {
        const size = i === chunks - 1 ? bytes - (chunkSize * i) : chunkSize;
        await this.acquireChunk(size);
      }
      return;
    }
    
    return this.acquireChunk(bytes);
  }

  /**
   * 请求发送数据块
   */
  async acquireChunk(bytes) {
    // 如果令牌足够，立即返回
    if (this.tokens >= bytes) {
      this.tokens -= bytes;
      this.currentBytes += bytes;
      return;
    }
    
    // 否则加入等待队列
    return new Promise((resolve) => {
      this.waiting.push({ bytes, resolve });
    });
  }

  /**
   * 获取当前速度
   */
  getCurrentSpeed() {
    const now = Date.now();
    const elapsed = (now - this.lastResetTime) / 1000;
    
    if (elapsed > 0) {
      return this.currentBytes / elapsed;
    }
    
    return 0;
  }

  /**
   * 设置最大速度
   */
  setMaxSpeed(maxBytesPerSecond) {
    this.maxBytesPerSecond = maxBytesPerSecond;
    this.tokens = Math.min(this.tokens, maxBytesPerSecond);
    logger.info(`流量限制已更新: ${(maxBytesPerSecond / 1024 / 1024).toFixed(2)} MB/s`);
  }

  /**
   * 获取统计信息
   */
  getStats() {
    return {
      maxSpeed: this.maxBytesPerSecond,
      currentSpeed: this.getCurrentSpeed(),
      tokensRemaining: this.tokens,
      waitingCount: this.waiting.length
    };
  }

  /**
   * 清理资源
   */
  destroy() {
    if (this.resetInterval) {
      clearInterval(this.resetInterval);
      this.resetInterval = null;
    }
    
    // 释放所有等待的 Promise
    while (this.waiting.length > 0) {
      const { resolve } = this.waiting.shift();
      resolve();
    }
    
    logger.info('流量限制器已销毁');
  }
}

// 创建全局实例
const uploadLimiter = new RateLimiter(170 * 1024 * 1024); // 170 MB/s 上传
const downloadLimiter = new RateLimiter(170 * 1024 * 1024); // 170 MB/s 下载

module.exports = {
  RateLimiter,
  uploadLimiter,
  downloadLimiter
};
